

class TerrienData {
    public height: number
    public index: number
    public obj: TerrianPhyObject
    public Destroy(parent: RandomTerrien) {
        if (this.obj != null && this.obj.body != null) {
            parent.World.DestroyBody(this.obj.body)
            this.obj.body = null
        }
        this.obj.Release()
    }

}

class Terrien {
    public up: TerrienData
    public down: TerrienData
    public index: number

    public Destroy(parent: RandomTerrien) {
        if (this.up != null) {
            this.up.Destroy(parent)
            this.up = null
        }
        if (this.down != null) {
            this.down.Destroy(parent)
            this.down = null
        }
    }
}

class RandomTerrien {
    private _maxLength: number
    private _tall: number
    private _spaceRate: number
    private _cellWidth: number
    private _cellCount: number
    private _phyScene: TarzanScene
    private _Player: PlayerPhyObject
    public get World(): Box2D.Dynamics.b2World {
        return this._phyScene.World
    }
    public get Player(): PlayerPhyObject {
        return this._Player
    }
    public get Backgroud(): egret.DisplayObjectContainer {
        return this._phyScene.Background
    }
    constructor(scene: TarzanScene, player: PlayerPhyObject) {
        this._maxLength = 2 * core.App.StageUtils.getWidth()
        this._tall = core.App.StageUtils.getHeight()
        this._spaceRate = 0.3
        this._cellWidth = 60
        this._zoomHeight = 200
        this._cellCount = Math.ceil(this._maxLength / this._cellWidth / 2) * 2
        this._curIndex = -this._cellCount / 2
        this._phyScene = scene
        this._Player = player
        this._terrien = new Array<Terrien>(this._cellCount)
        console.log("RandomTerrien:  " + this._maxLength + "," + this._tall)
    }

    private _fromIndex: number = 0
    private _toIndex: number = 0
    private _terrien: Array<Terrien> = null
    private _inited: boolean = false
    private _realIndex: number = 0
    public get Score(): number {
        return this._realIndex
    }
    private _curIndex: number = 0
    private _zoomHeight: number
    public LookAt(x, y: number) {
        this.RandomData(x)
    }
    public RandomData(index: number) {
        this._realIndex = Math.ceil(index / this._cellWidth)
        index = this._realIndex + this._cellCount / 2
        if (this._inited && this._curIndex == index) {
            return
        }
        console.log("RandomData:" + index)

        for (let n = this._curIndex; n < index; n++) {
            let i = n % this._cellCount
            if (i < 0) {
                i = i + this._cellCount
            }
            if (this._terrien[i] == null) {
                this._terrien[i] = new Terrien()
            } else {
                this._terrien[i].Destroy(this)
            }
            this._terrien[i].index = n
            this._terrien[i].up = new TerrienData()
            this._terrien[i].up.index = n
            this._terrien[i].up.height = this._zoomHeight + Math.ceil(Math.random() * (this._tall * (1 - this._spaceRate))) / 2
            if (n < 10) {
                this._terrien[i].up.height = this._zoomHeight + this._tall / 6
            }

            this._terrien[i].down = new TerrienData()
            this._terrien[i].down.index = n
            this._terrien[i].down.height = this._zoomHeight + Math.ceil(Math.random() * (this._tall * (1 - this._spaceRate))) / 2
            if (n < 10) {
                this._terrien[i].down.height = this._zoomHeight + this._tall / 4
            }

            {

                {
                    let t = this._terrien[i].up
                    let p = 1

                    let x = PhyScene.PhyLen(n * this._cellWidth)
                    let y = p * PhyScene.PhyLen(this._zoomHeight + this._tall / 2 - t.height / 2)
                    let width = t.height
                    let height = this._cellWidth

                    t.obj = new TerrianPhyObject(this.Backgroud, this.World, width, height, x, y, p)
                }

                {
                    let t = this._terrien[i].down
                    let p = -1

                    let x = PhyScene.PhyLen(n * this._cellWidth)
                    let y = p * PhyScene.PhyLen(this._zoomHeight + this._tall / 2 - t.height / 2)
                    let width = t.height
                    let height = this._cellWidth

                    t.obj = new TerrianPhyObject(this.Backgroud, this.World, width, height, x, y, p)
                }
            }
        }

        this._curIndex = index
        this._inited = true

        /*
        if (this._inited && index > this._fromIndex + this._maxLength / 4 && index < this._toIndex - this._maxLength / 4) {
            return
        }
        
        this._fromIndex = index - this._maxLength / 2
        this._toIndex = index + this._maxLength / 2
        */
    }

    public onTap() {
        let i = (this._realIndex + 2) % this._cellCount
        let t = this._terrien[i]
        console.log("Destroy:  " + t)
        //t.Destroy(this)
    }

    public Role: RolePhyObject
    private _flySound: egret.Sound
    public makeTheRole() {
        this.releaseTheRole()

        let i = (this._realIndex + 1) % this._cellCount
        let t = this._terrien[i]

        if (this._flySound == null) {
            this._flySound = RES.getRes("fly_mp3")
        }
        this._flySound.play(0, 1)

        this.Role = new RolePhyObject(this.Backgroud, this.World, this.Player, t.down.obj)
    }

    public releaseTheRole() {
        if (this.Role != null) {
            this.Role.Release()
        }
    }

    public Refresh() {
        if (this.Role != null) {
            this.Role.RefreshPos()
        }
    }

}